#requires -version 2
function Get-NaSIS {
<#
.SYNOPSIS
	Returns the schedule for a given destination or all destinations. This command 
    must be executed on the destination filer.
.DESCRIPTION
	Returns the schedule for a given destination or all destinations. This command 
    must be executed on the destination filer. Currently, the schedules is in 
    /etc/snapmirror.conf.
.PARAMETER Path
    The full path of the SIS volume, /vol/<vol_name>.
.PARAMETER Server
   	NaServer to query
.EXAMPLE
    Get-NaSIS
.OUTPUTS
	NetApp.SDK.NaSnapMirrorSchedule[]
.Link
	Set-NaSnapMirrorSchedule
	Get-NaSnapMirror
	Set-NaSnapMirror
	Initialize-NaSnapMirror
	Update-NaSnapMirror
#> 
	[CmdletBinding(SupportsShouldProcess=$False,SupportsTransactions=$False,ConfirmImpact="Low",DefaultParameterSetName="")]
	param(
		[Parameter(Position=0,ValueFromPipelineByPropertyName=$TRUE)]
		[string]
		$Path,
	
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer]
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("sis-status")
		$request.AddNewChild("verbose",$true)
		if ($Path){
			$request.AddNewChild("path",$Path)
		}
		try {
			$result = ([xml]$server.InvokeElem($request)).results
		}
		catch [NetApp.Manage.NaApiFailedException]{
            Write-Warning $_.Exception.GetBaseException().message
            $result = $null
            continue;
        }
		if ($?){
			$result."sis-object"."dense-status" | % {
				return New-Object NetApp.SDK.NaSIS -ArgumentList @(
					$_."path",
					$_."progress",
					$_."schedule",
					$_."state",
					$_."status",
					$_."type",
					$_."checkpoint-op-type",
					$_."checkpoint-progress",
					$_."checkpoint-stage",
					$_."checkpoint-sub-stage",
					$_."checkpoint-time",
					(ConvertFrom-NaTime $_."last-operation-begin-timestamp"),
					(ConvertFrom-NaTime $_."last-operation-end-timestamp"),
					$_."last-operation-error",
					$_."last-operation-size"					
				)
			}
		}
	}
}
function Set-NaSIS {
<#
.SYNOPSIS
	Setup or modify the SIS operation schedule or options for a SIS volume. Currently, 
	only used to config schedule. 
.DESCRIPTION
	Setup or modify the SIS operation schedule or options for a SIS volume. Currently,
	only used to config schedule. 
.PARAMETER PATH
	The full path of the SIS volume, /vol/<vol_name>. 
.PARAMETER Schedule
	The schedule string for the SIS operation. The format of the schedule: 
	day_list[@hour_list] or hour_list[@day_list] or auto 
	
	The day_list specifies which days of the week the SIS operation should run. It is
	a comma-separated list of the first three letters of the day: sun, mon, tue, wed, 
	thu, fri, sat. The names are not case sensitive. 
	
	Day ranges such as mon-fri can also be given. The default day_list is sun-sat. 
	
	The hour_list specifies which hours of the day the SIS operation should run on each
	scheduled day. The hour_list is a comma-separated list of the integers from 0 to 23. 
	Hour ranges such as 8-17 are allowed. Step values can be used in conjuction with 
	ranges. For example, 0-23/2 means "every two hours". 
	
	The default hour_list is 0, i.e. midnight on the morning of each scheduled day. 
	If "-" is specified, no schedule is set. When a non-SIS volume is enabled the 
	first time, an initial schedule is assigned to the volume. This initial schedule 
	is sun-sat@0, that means "once everyday at midnight". 
	
	The "auto" schedule string means the SIS operation will be triggered by the amount
	of new data written to the volume. The criterion is subject to be changed later. 
.PARAMETER Server
   	NaServer to query
.EXAMPLE
	Set-NaSIS /vol/vol1 auto
	
	Set sis on /vol/vol1 to auto
.EXAMPLE
	Set-NaSIS /vol/vol1 sat-sun@8,20
	
	Set sis on /vol/vol1 to run sat-sun at 8am and 8pm
.Link
	Get-NaSIS
	Start-NaSIS	
	Stop-NaSIS
	Enable-NaSIS
	Disable-NaSIS
#> 

	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="Low",DefaultParameterSetName="")]
	param(
		[Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$TRUE)]
		[string]
		$Path,
		
		[Parameter(Mandatory=$true,Position=1,ValueFromPipelineByPropertyName=$TRUE)]
		[string]
		$Schedule,
				
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer]
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("sis-set-config")
		$request.AddNewChild("path",$Path)
		$request.AddNewChild("schedule",$Schedule)
		if ($pscmdlet.ShouldProcess($Server.Server,"Setting $($path) SIS to $($Schedule)")){
			try {
				$server.InvokeElem($request) | out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				continue;
			}
			if ($?) {
				Get-NaSIS -Path $Path -Server $Server
			}
		}
	}
}
function Enable-NaSIS {
<#
.SYNOPSIS
	Enables SIS on a volume. 
.DESCRIPTION
	Enables SIS on a volume. On a non-SnapVault secondary volume, the SIS operation 
	will be started periodically according to a per-volume schedule. On a SnapVault 
	secondary volume, the SIS operation will be kicked off at the end of the 
	SnapVault transfer. See the Set-NaSIS cndlet for the details about the schedule. 
	Users can also start SIS operation with Start-NaSIS cmdlet.
.PARAMETER PATH
	The full path of the SIS volume, /vol/<vol_name>. Only one path can be specified 
	at a time. The volume must be online to enable SIS operation.  
.PARAMETER Server
   	NaServer to query
.EXAMPLE
	Enable-NaSIS /vol/vol1
.Link
	Get-NaSIS
	Set-NaSIS
	Start-NaSIS	
	Stop-NaSIS
	Disable-NaSIS
#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="Low",DefaultParameterSetName="")]
	param(
		[Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$TRUE)]
		[string]
		$Path,
		
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer]
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("sis-enable")
		$request.AddNewChild("path",$Path)
		if ($pscmdlet.ShouldProcess($Server.Server,"Enabling SIS on $($path)")){
			try {
				$server.InvokeElem($request) | out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				continue;
			}
			if ($?) {
				Get-NaSIS -Path $Path -Server $Server
			}
		}
	}
}
function Disable-NaSIS {
<#
.SYNOPSIS
	Disables SIS operation on a volume.
.DESCRIPTION
	Disables SIS operation on a volume. If the SIS operation is active on the volume,
	it needs to be stopped by "Stop-NaSIS" cmdlet before disabling. 
.PARAMETER PATH
	The full path of the SIS volume, /vol/<vol_name>. Only one path can be specified
	at a time.  
.PARAMETER Server
   	NaServer to query
.EXAMPLE
	Disable-NaSIS /vol/vol1
.Link
	Get-NaSIS
	Set-NaSIS
	Start-NaSIS	
	Stop-NaSIS
	Enable-NaSIS
#>
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="Low",DefaultParameterSetName="")]
	param(
		[Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$TRUE)]
		[string]
		$Path,
		
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer]
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("sis-disable")
		$request.AddNewChild("path",$Path)
		if ($pscmdlet.ShouldProcess($Server.Server,"Disabling SIS on $($path)")){
			try {
				$server.InvokeElem($request) | out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				continue;
			}
			if ($?) {
				Get-NaSIS -Path $Path -Server $Server
			}
		}
	}
}
function Start-NaSIS {
<#
.SYNOPSIS
	Start SIS operation on a SIS volume.
.DESCRIPTION
	Start SIS operation on a SIS volume. The volume must already be sis enabled. 
	If the SIS operation is already active on the volume, this cmd will fail. 
.PARAMETER PATH
	The full path of the SIS volume, /vol/<vol_name>. Only one path can be specified.
	at a time.  The volume must be online to enable SIS operation. 
.PARAMETER Scan
	The SIS operation will scan the file system to process all the existing data.
.PARAMETER RestartCheckPoint
	The SIS operation will restart from previous checkpoint without checking for validity. 
	This option should be used along with "scan" switch
.PARAMETER DeleteCheckPoint
	If applied then the SIS operation will delete existing checkpoint and start the SIS
	operation from the beginning.
.PARAMETER Server
   	NaServer to query
.EXAMPLE
	Start-NaSIS -path /vol/vol1
.Link
	Get-NaSIS
	Set-NaSIS
	Stop-NaSIS
	Enable-NaSIS
	Disable-NaSIS
#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="Low",DefaultParameterSetName="start")]
	param(
		[Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$TRUE,ParameterSetName="start")]
		[Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$TRUE,ParameterSetName="scan")]
		[Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$TRUE,ParameterSetName="restart")]
		[string]
		$Path,
		
		[Parameter(Mandatory=$true,ParameterSetName="scan")]
		[switch]
		$Scan,
		
		[Parameter(Mandatory=$False,ParameterSetName="scan")]
		[switch]
		$RestartCheckPoint,
		
		[Parameter(Mandatory=$true,ParameterSetName="restart")]
		[switch]
		$DeleteCheckPoint,
		
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer]
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("sis-start")
		$request.AddNewChild("path",$Path)
		switch ($PSCmdlet.ParameterSetName) 
		{
			"start"
			{
				$msg = "Starting SIS on $($path)"
			}
			"scan" 
			{
				$request.AddNewChild("scan",$True)
				$msg = "Starting SIS Scan on $($path)"
				if ($RestartCheckPoint) {
					$request.AddNewChild("restart-checkpoint",$True)
					$msg = "Resuming SIS Scan on $($path)"
				}
			}
			"restart"
			{
				$msg = "Restarting SIS on $($path)"
				$request.AddNewChild("delete-checkpoint",$True)
			}
		}
		if ($pscmdlet.ShouldProcess($Server.Server,$msg)){
			try {
				$server.InvokeElem($request) | out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				continue;
			}
			if ($?) {
				Get-NaSIS -Path $Path -Server $Server
			}
		}
	}
}
function Stop-NaSIS {
<#
.SYNOPSIS
	Abort currently active SIS operation on the volume. 
.DESCRIPTION
	Abort currently active SIS operation on the volume. The SIS operation will 
	remain enabled and the operation can be resumed by Start-NaSIS, SnapVault 
	transfer, or the scheduler. 
.PARAMETER PATH
	The full path of the SIS volume, /vol/<vol_name>.
.PARAMETER Server
   	NaServer to query
.EXAMPLE
	Stop-NaSIS /vol/vol1
.Link
	Get-NaSIS
	Set-NaSIS
	Start-NaSIS	
	Enable-NaSIS
	Disable-NaSIS
#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="Low",DefaultParameterSetName="")]
	param(
		[Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$TRUE)]
		[string]
		$Path,
		
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer]
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("sis-stop")
		$request.AddNewChild("path",$Path)
		if ($pscmdlet.ShouldProcess($Server.Server,"Stoping all SIS operations on $($path)")){
			try {
				$server.InvokeElem($request) | out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				continue;
			}
			if ($?) {
				Get-NaSIS -Path $Path -Server $Server
			}
		}
	}
}